// Copyright (c) 2024，D-Robotics.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/****************************************************************************
*
*    Copyright (c) 2005 - 2023 by Vivante Corp.  All rights reserved.
*
*    The material in this file is confidential and contains trade secrets
*    of Vivante Corporation. This is proprietary information owned by
*    Vivante Corporation. No part of this work may be disclosed,
*    reproduced, copied, transmitted, or used in any way for any purpose,
*    without the express written permission of Vivante Corporation.
*
*****************************************************************************/


#ifndef __gc_hal_profiler_h_
#define __gc_hal_profiler_h_

#include "shared/gc_hal_profiler_shared.h"

#ifdef __cplusplus
extern "C" {
#endif

#define GLVERTEX_OBJECT         10
#define GLVERTEX_OBJECT_BYTES   11

#define GLINDEX_OBJECT          20
#define GLINDEX_OBJECT_BYTES    21

#define GLTEXTURE_OBJECT        30
#define GLTEXTURE_OBJECT_BYTES  31

#define GLBUFOBJ_OBJECT         40
#define GLBUFOBJ_OBJECT_BYTES   41

#define    ES11_CALLS              151
#define    ES11_DRAWCALLS          (ES11_CALLS             + 1)
#define    ES11_STATECHANGECALLS   (ES11_DRAWCALLS         + 1)
#define    ES11_POINTCOUNT         (ES11_STATECHANGECALLS  + 1)
#define    ES11_LINECOUNT          (ES11_POINTCOUNT        + 1)
#define    ES11_TRIANGLECOUNT      (ES11_LINECOUNT         + 1)

#define    ES30_CALLS              159
#define    ES30_DRAWCALLS          (ES30_CALLS             + 1)
#define    ES30_STATECHANGECALLS   (ES30_DRAWCALLS         + 1)
#define    ES30_POINTCOUNT         (ES30_STATECHANGECALLS  + 1)
#define    ES30_LINECOUNT          (ES30_POINTCOUNT        + 1)
#define    ES30_TRIANGLECOUNT      (ES30_LINECOUNT         + 1)

#define    VG11_CALLS              88
#define    VG11_DRAWCALLS          (VG11_CALLS              + 1)
#define    VG11_STATECHANGECALLS   (VG11_DRAWCALLS          + 1)
#define    VG11_FILLCOUNT          (VG11_STATECHANGECALLS   + 1)
#define    VG11_STROKECOUNT        (VG11_FILLCOUNT          + 1)
/* End of Driver API ID Definitions. */

/* HAL & MISC IDs. */
#define HAL_VERTBUFNEWBYTEALLOC    1
#define HAL_VERTBUFTOTALBYTEALLOC  (HAL_VERTBUFNEWBYTEALLOC     + 1)
#define HAL_VERTBUFNEWOBJALLOC     (HAL_VERTBUFTOTALBYTEALLOC   + 1)
#define HAL_VERTBUFTOTALOBJALLOC   (HAL_VERTBUFNEWOBJALLOC      + 1)
#define HAL_INDBUFNEWBYTEALLOC     (HAL_VERTBUFTOTALOBJALLOC    + 1)
#define HAL_INDBUFTOTALBYTEALLOC   (HAL_INDBUFNEWBYTEALLOC      + 1)
#define HAL_INDBUFNEWOBJALLOC      (HAL_INDBUFTOTALBYTEALLOC    + 1)
#define HAL_INDBUFTOTALOBJALLOC    (HAL_INDBUFNEWOBJALLOC       + 1)
#define HAL_TEXBUFNEWBYTEALLOC     (HAL_INDBUFTOTALOBJALLOC     + 1)
#define HAL_TEXBUFTOTALBYTEALLOC   (HAL_TEXBUFNEWBYTEALLOC      + 1)
#define HAL_TEXBUFNEWOBJALLOC      (HAL_TEXBUFTOTALBYTEALLOC    + 1)
#define HAL_TEXBUFTOTALOBJALLOC    (HAL_TEXBUFNEWOBJALLOC       + 1)

#define GPU_CYCLES            1
#define GPU_READ64BYTE        (GPU_CYCLES            + 1)
#define GPU_WRITE64BYTE       (GPU_READ64BYTE        + 1)
#define GPU_TOTALCYCLES       (GPU_WRITE64BYTE       + 1)
#define GPU_IDLECYCLES        (GPU_TOTALCYCLES       + 1)

#define VS_INSTCOUNT          1
#define VS_BRANCHINSTCOUNT    (VS_INSTCOUNT          + 1)
#define VS_TEXLDINSTCOUNT     (VS_BRANCHINSTCOUNT    + 1)
#define VS_RENDEREDVERTCOUNT  (VS_TEXLDINSTCOUNT     + 1)
#define VS_SOURCE             (VS_RENDEREDVERTCOUNT  + 1)
#define VS_NONIDLESTARVECOUNT (VS_SOURCE             + 1)
#define VS_STARVELCOUNT       (VS_NONIDLESTARVECOUNT + 1)
#define VS_STALLCOUNT         (VS_STARVELCOUNT       + 1)
#define VS_PROCESSCOUNT       (VS_STALLCOUNT         + 1)

#define PS_INSTCOUNT          1
#define PS_BRANCHINSTCOUNT    (PS_INSTCOUNT          + 1)
#define PS_TEXLDINSTCOUNT     (PS_BRANCHINSTCOUNT    + 1)
#define PS_RENDEREDPIXCOUNT   (PS_TEXLDINSTCOUNT     + 1)
#define PS_SOURCE             (PS_RENDEREDPIXCOUNT   + 1)
#define PS_NONIDLESTARVECOUNT (PS_SOURCE             + 1)
#define PS_STARVELCOUNT       (PS_NONIDLESTARVECOUNT + 1)
#define PS_STALLCOUNT         (PS_STARVELCOUNT       + 1)
#define PS_PROCESSCOUNT       (PS_STALLCOUNT         + 1)
#define PS_SHADERCYCLECOUNT   (PS_PROCESSCOUNT       + 1)

#define PA_INVERTCOUNT        1
#define PA_INPRIMCOUNT        (PA_INVERTCOUNT      + 1)
#define PA_OUTPRIMCOUNT       (PA_INPRIMCOUNT      + 1)
#define PA_DEPTHCLIPCOUNT     (PA_OUTPRIMCOUNT     + 1)
#define PA_TRIVIALREJCOUNT    (PA_DEPTHCLIPCOUNT   + 1)
#define PA_CULLCOUNT          (PA_TRIVIALREJCOUNT  + 1)
#define PA_NONIDLESTARVECOUNT (PA_CULLCOUNT        + 1)
#define PA_STARVELCOUNT       (PA_NONIDLESTARVECOUNT + 1)
#define PA_STALLCOUNT         (PA_STARVELCOUNT     + 1)
#define PA_PROCESSCOUNT       (PA_STALLCOUNT       + 1)

#define SE_TRIANGLECOUNT        1
#define SE_LINECOUNT            (SE_TRIANGLECOUNT        + 1)
#define SE_STARVECOUNT          (SE_LINECOUNT            + 1)
#define SE_STALLCOUNT           (SE_STARVECOUNT          + 1)
#define SE_RECEIVETRIANGLECOUNT (SE_STALLCOUNT           + 1)
#define SE_SENDTRIANGLECOUNT    (SE_RECEIVETRIANGLECOUNT + 1)
#define SE_RECEIVELINESCOUNT    (SE_SENDTRIANGLECOUNT    + 1)
#define SE_SENDLINESCOUNT       (SE_RECEIVELINESCOUNT    + 1)
#define SE_NONIDLESTARVECOUNT   (SE_SENDLINESCOUNT       + 1)
#define SE_PROCESSCOUNT         (SE_NONIDLESTARVECOUNT   + 1)

#define RA_VALIDPIXCOUNT       1
#define RA_TOTALQUADCOUNT      (RA_VALIDPIXCOUNT      + 1)
#define RA_VALIDQUADCOUNTEZ    (RA_TOTALQUADCOUNT     + 1)
#define RA_TOTALPRIMCOUNT      (RA_VALIDQUADCOUNTEZ   + 1)
#define RA_PIPECACHEMISSCOUNT  (RA_TOTALPRIMCOUNT     + 1)
#define RA_PREFCACHEMISSCOUNT  (RA_PIPECACHEMISSCOUNT + 1)
#define RA_EEZCULLCOUNT        (RA_PREFCACHEMISSCOUNT + 1)
#define RA_NONIDLESTARVECOUNT  (RA_EEZCULLCOUNT       + 1)
#define RA_STARVELCOUNT        (RA_NONIDLESTARVECOUNT + 1)
#define RA_STALLCOUNT          (RA_STARVELCOUNT       + 1)
#define RA_PROCESSCOUNT        (RA_STALLCOUNT         + 1)

#define TX_TOTBILINEARREQ      1
#define TX_TOTTRILINEARREQ     (TX_TOTBILINEARREQ      + 1)
#define TX_TOTDISCARDTEXREQ    (TX_TOTTRILINEARREQ     + 1)
#define TX_TOTTEXREQ           (TX_TOTDISCARDTEXREQ    + 1)
#define TX_MEMREADCOUNT        (TX_TOTTEXREQ           + 1)
#define TX_MEMREADIN8BCOUNT    (TX_MEMREADCOUNT        + 1)
#define TX_CACHEMISSCOUNT      (TX_MEMREADIN8BCOUNT    + 1)
#define TX_CACHEHITTEXELCOUNT  (TX_CACHEMISSCOUNT      + 1)
#define TX_CACHEMISSTEXELCOUNT (TX_CACHEHITTEXELCOUNT  + 1)
#define TX_NONIDLESTARVECOUNT  (TX_CACHEMISSTEXELCOUNT + 1)
#define TX_STARVELCOUNT        (TX_NONIDLESTARVECOUNT  + 1)
#define TX_STALLCOUNT          (TX_STARVELCOUNT        + 1)
#define TX_PROCESSCOUNT        (TX_STALLCOUNT          + 1)

#define PE_KILLEDBYCOLOR      1
#define PE_KILLEDBYDEPTH      (PE_KILLEDBYCOLOR     + 1)
#define PE_DRAWNBYCOLOR       (PE_KILLEDBYDEPTH     + 1)
#define PE_DRAWNBYDEPTH       (PE_DRAWNBYCOLOR      + 1)

#define MC_READREQ8BPIPE      1
#define MC_READREQ8BIP        (MC_READREQ8BPIPE     + 1)
#define MC_WRITEREQ8BPIPE     (MC_READREQ8BIP       + 1)
#define MC_AXIMINLATENCY      (MC_WRITEREQ8BPIPE    + 1)
#define MC_AXIMAXLATENCY      (MC_AXIMINLATENCY     + 1)
#define MC_AXITOTALLATENCY    (MC_AXIMAXLATENCY     + 1)
#define MC_AXISAMPLECOUNT     (MC_AXITOTALLATENCY   + 1)

#define AXI_READREQSTALLED    1
#define AXI_WRITEREQSTALLED   (AXI_READREQSTALLED   + 1)
#define AXI_WRITEDATASTALLED  (AXI_WRITEREQSTALLED  + 1)

#define FE_DRAWCOUNT          1
#define FE_OUTVERTEXCOUNT     (FE_DRAWCOUNT         + 1)
#define FE_STALLCOUNT         (FE_OUTVERTEXCOUNT    + 1)
#define FE_STARVECOUNT        (FE_STALLCOUNT        + 1)

#define PVS_INSTRCOUNT        1
#define PVS_ALUINSTRCOUNT     (PVS_INSTRCOUNT       + 1)
#define PVS_TEXINSTRCOUNT     (PVS_ALUINSTRCOUNT    + 1)
#define PVS_ATTRIBCOUNT       (PVS_TEXINSTRCOUNT    + 1)
#define PVS_UNIFORMCOUNT      (PVS_ATTRIBCOUNT      + 1)
#define PVS_FUNCTIONCOUNT     (PVS_UNIFORMCOUNT     + 1)
#define PVS_SOURCE            (PVS_FUNCTIONCOUNT    + 1)

#define PPS_INSTRCOUNT        1
#define PPS_ALUINSTRCOUNT     (PPS_INSTRCOUNT       + 1)
#define PPS_TEXINSTRCOUNT     (PPS_ALUINSTRCOUNT    + 1)
#define PPS_ATTRIBCOUNT       (PPS_TEXINSTRCOUNT    + 1)
#define PPS_UNIFORMCOUNT      (PPS_ATTRIBCOUNT      + 1)
#define PPS_FUNCTIONCOUNT     (PPS_UNIFORMCOUNT     + 1)
#define PPS_SOURCE            (PPS_FUNCTIONCOUNT    + 1)
/* End of MISC Counter IDs. */

#define VPG(x) (gcoPROFILER_getVPGConst(x))

enum gceVPG {
    VPHEADER,
    INFO,
    FRAME,
    VPTIME,
    ES11,
    VG11,
    HW,
    MULTI_GPU,
    PROG,
    ES11DRAW,
    MEM,
    PVS,
    PPS,
    ES11_TIME,
    ES30,
    ES30_DRAW,
    ES30_TIME,
    FINISH,
    END,
    COMPUTE30,
    BLT,
    CLUSTER,
};

/* Category Constants. */
#define VPG_HAL              0x080000
#define VPG_GPU              0x0a0000
#define VPG_VS               0x0b0000
#define VPG_PS               0x0c0000
#define VPG_PA               0x0d0000
#define VPG_SETUP            0x0e0000
#define VPG_RA               0x0f0000
#define VPG_TX               0x100000
#define VPG_PE               0x110000
#define VPG_MC               0x120000
#define VPG_AXI              0x130000
#define VPG_VG11_TIME        0x220000
#define VPG_FE               0x230000
#define VPNG_FE              0x250000
#define VPNG_VS              0x260000
#define VPNG_PS              0x270000
#define VPNG_PA              0x280000
#define VPNG_SETUP           0x290000
#define VPNG_RA              0x2a0000
#define VPNG_TX              0x2b0000
#define VPNG_PE              0x2c0000
#define VPNG_MCC             0x2d0000
#define VPNG_MCZ             0x2e0000
#define VPNG_HI              0x2f0000
#define VPNG_L2              0x300000
#define VPNG_NN              0x310000
#define VPNG_TP              0x320000
#define VPG_CLUSTER          0x68000000

/* Info. */
#define VPC_INFOCOMPANY         (VPG(INFO) + 1)
#define VPC_INFOVERSION         (VPC_INFOCOMPANY + 1)
#define VPC_INFORENDERER        (VPC_INFOVERSION + 1)
#define VPC_INFOREVISION        (VPC_INFORENDERER + 1)
#define VPC_INFODRIVER          (VPC_INFOREVISION + 1)
#define VPC_INFODRIVERMODE      (VPC_INFODRIVER + 1)
#define VPC_INFOSCREENSIZE      (VPC_INFODRIVERMODE + 1)
#define VPC_INFOASICMODE        (VPC_INFOSCREENSIZE + 1)

/* Counter Constants. */
#define VPC_ELAPSETIME          (VPG(VPTIME) + 1)
#define VPC_CPUTIME             (VPC_ELAPSETIME + 1)

#define VPC_MEMMAXRES           (VPG(MEM) + 1)
#define VPC_MEMSHARED           (VPC_MEMMAXRES + 1)
#define VPC_MEMUNSHAREDDATA     (VPC_MEMSHARED + 1)
#define VPC_MEMUNSHAREDSTACK    (VPC_MEMUNSHAREDDATA + 1)

/* OpenGL ES11 Statics Counter IDs. */
#define    VPC_ES11CALLS            (VPG(ES11) +    ES11_CALLS)
#define    VPC_ES11DRAWCALLS        (VPG(ES11) +    ES11_DRAWCALLS)
#define    VPC_ES11STATECHANGECALLS (VPG(ES11) +    ES11_STATECHANGECALLS)
#define    VPC_ES11POINTCOUNT       (VPG(ES11) +    ES11_POINTCOUNT)
#define    VPC_ES11LINECOUNT        (VPG(ES11) +    ES11_LINECOUNT)
#define    VPC_ES11TRIANGLECOUNT    (VPG(ES11) +    ES11_TRIANGLECOUNT)

/* OpenGL ES30 Statistics Counter IDs. */
#define    VPC_ES30CALLS            (VPG(ES30) +    ES30_CALLS)
#define    VPC_ES30DRAWCALLS        (VPG(ES30) +    ES30_DRAWCALLS)
#define    VPC_ES30STATECHANGECALLS (VPG(ES30) +    ES30_STATECHANGECALLS)
#define    VPC_ES30POINTCOUNT       (VPG(ES30) +    ES30_POINTCOUNT)
#define    VPC_ES30LINECOUNT        (VPG(ES30) +    ES30_LINECOUNT)
#define    VPC_ES30TRIANGLECOUNT    (VPG(ES30) +    ES30_TRIANGLECOUNT)

/* OpenVG Statistics Counter IDs. */
#define    VPC_VG11CALLS            (VPG(VG11) +    VG11_CALLS)
#define    VPC_VG11DRAWCALLS        (VPG(VG11) +    VG11_DRAWCALLS)
#define    VPC_VG11STATECHANGECALLS (VPG(VG11) +    VG11_STATECHANGECALLS)
#define    VPC_VG11FILLCOUNT        (VPG(VG11) +    VG11_FILLCOUNT)
#define    VPC_VG11STROKECOUNT      (VPG(VG11) +    VG11_STROKECOUNT)

/* HAL Counters. */
#define VPC_HALVERTBUFNEWBYTEALLOC      (VPG_HAL + HAL_VERTBUFNEWBYTEALLOC)
#define VPC_HALVERTBUFTOTALBYTEALLOC    (VPG_HAL + HAL_VERTBUFTOTALBYTEALLOC)
#define VPC_HALVERTBUFNEWOBJALLOC       (VPG_HAL + HAL_VERTBUFNEWOBJALLOC)
#define VPC_HALVERTBUFTOTALOBJALLOC     (VPG_HAL + HAL_VERTBUFTOTALOBJALLOC)
#define VPC_HALINDBUFNEWBYTEALLOC       (VPG_HAL + HAL_INDBUFNEWBYTEALLOC)
#define VPC_HALINDBUFTOTALBYTEALLOC     (VPG_HAL + HAL_INDBUFTOTALBYTEALLOC)
#define VPC_HALINDBUFNEWOBJALLOC        (VPG_HAL + HAL_INDBUFNEWOBJALLOC)
#define VPC_HALINDBUFTOTALOBJALLOC      (VPG_HAL + HAL_INDBUFTOTALOBJALLOC)
#define VPC_HALTEXBUFNEWBYTEALLOC       (VPG_HAL + HAL_TEXBUFNEWBYTEALLOC)
#define VPC_HALTEXBUFTOTALBYTEALLOC     (VPG_HAL + HAL_TEXBUFTOTALBYTEALLOC)
#define VPC_HALTEXBUFNEWOBJALLOC        (VPG_HAL + HAL_TEXBUFNEWOBJALLOC)
#define VPC_HALTEXBUFTOTALOBJALLOC      (VPG_HAL + HAL_TEXBUFTOTALOBJALLOC)

/* HW: GPU Counters. */
#define VPC_GPUCYCLES                   (VPG_GPU + GPU_CYCLES)
#define VPC_GPUREAD64BYTE               (VPG_GPU + GPU_READ64BYTE)
#define VPC_GPUWRITE64BYTE              (VPG_GPU + GPU_WRITE64BYTE)
#define VPC_GPUTOTALCYCLES              (VPG_GPU + GPU_TOTALCYCLES)
#define VPC_GPUIDLECYCLES               (VPG_GPU + GPU_IDLECYCLES)

/* HW: Shader Counters. */
#define VPC_VSINSTCOUNT                 (VPG_VS + VS_INSTCOUNT)
#define VPC_VSBRANCHINSTCOUNT           (VPG_VS + VS_BRANCHINSTCOUNT)
#define VPC_VSTEXLDINSTCOUNT            (VPG_VS + VS_TEXLDINSTCOUNT)
#define VPC_VSRENDEREDVERTCOUNT         (VPG_VS + VS_RENDEREDVERTCOUNT)
#define VPC_VSNONIDLESTARVECOUNT        (VPG_VS + VS_NONIDLESTARVECOUNT)
#define VPC_VSSTARVELCOUNT              (VPG_VS + VS_STARVELCOUNT)
#define VPC_VSSTALLCOUNT                (VPG_VS + VS_STALLCOUNT)
#define VPC_VSPROCESSCOUNT              (VPG_VS + VS_PROCESSCOUNT)
/* HW: PS Count. */
#define VPC_PSINSTCOUNT                 (VPG_PS + PS_INSTCOUNT)
#define VPC_PSBRANCHINSTCOUNT           (VPG_PS + PS_BRANCHINSTCOUNT)
#define VPC_PSTEXLDINSTCOUNT            (VPG_PS + PS_TEXLDINSTCOUNT)
#define VPC_PSRENDEREDPIXCOUNT          (VPG_PS + PS_RENDEREDPIXCOUNT)
#define VPC_PSNONIDLESTARVECOUNT        (VPG_PS + PS_NONIDLESTARVECOUNT)
#define VPC_PSSTARVELCOUNT              (VPG_PS + PS_STARVELCOUNT)
#define VPC_PSSTALLCOUNT                (VPG_PS + PS_STALLCOUNT)
#define VPC_PSPROCESSCOUNT              (VPG_PS + PS_PROCESSCOUNT)
#define VPC_PSSHADERCYCLECOUNT          (VPG_PS + PS_SHADERCYCLECOUNT)

/* HW: PA Counters. */
#define VPC_PAINVERTCOUNT               (VPG_PA + PA_INVERTCOUNT)
#define VPC_PAINPRIMCOUNT               (VPG_PA + PA_INPRIMCOUNT)
#define VPC_PAOUTPRIMCOUNT              (VPG_PA + PA_OUTPRIMCOUNT)
#define VPC_PADEPTHCLIPCOUNT            (VPG_PA + PA_DEPTHCLIPCOUNT)
#define VPC_PATRIVIALREJCOUNT           (VPG_PA + PA_TRIVIALREJCOUNT)
#define VPC_PACULLCOUNT                 (VPG_PA + PA_CULLCOUNT)
#define VPC_PANONIDLESTARVECOUNT        (VPG_PA + PA_NONIDLESTARVECOUNT)
#define VPC_PASTARVELCOUNT              (VPG_PA + PA_STARVELCOUNT)
#define VPC_PASTALLCOUNT                (VPG_PA + PA_STALLCOUNT)
#define VPC_PAPROCESSCOUNT              (VPG_PA + PA_PROCESSCOUNT)

/* HW: Setup Counters. */
#define VPC_SETRIANGLECOUNT             (VPG_SETUP + SE_TRIANGLECOUNT)
#define VPC_SELINECOUNT                 (VPG_SETUP + SE_LINECOUNT)
#define VPC_SESTARVECOUNT               (VPG_SETUP + SE_STARVECOUNT)
#define VPC_SESTALLCOUNT                (VPG_SETUP + SE_STALLCOUNT)
#define VPC_SERECEIVETRIANGLECOUNT      (VPG_SETUP + SE_RECEIVETRIANGLECOUNT)
#define VPC_SESENDTRIANGLECOUNT         (VPG_SETUP + SE_SENDTRIANGLECOUNT)
#define VPC_SERECEIVELINESCOUNT         (VPG_SETUP + SE_RECEIVELINESCOUNT)
#define VPC_SESENDLINESCOUNT            (VPG_SETUP + SE_SENDLINESCOUNT)
#define VPC_SENONIDLESTARVECOUNT        (VPG_SETUP + SE_NONIDLESTARVECOUNT)
#define VPC_SEPROCESSCOUNT              (VPG_SETUP + SE_PROCESSCOUNT)

/* HW: RA Counters. */
#define VPC_RAVALIDPIXCOUNT             (VPG_RA + RA_VALIDPIXCOUNT)
#define VPC_RATOTALQUADCOUNT            (VPG_RA + RA_TOTALQUADCOUNT)
#define VPC_RAVALIDQUADCOUNTEZ          (VPG_RA + RA_VALIDQUADCOUNTEZ)
#define VPC_RATOTALPRIMCOUNT            (VPG_RA + RA_TOTALPRIMCOUNT)
#define VPC_RAPIPECACHEMISSCOUNT        (VPG_RA + RA_PIPECACHEMISSCOUNT)
#define VPC_RAPREFCACHEMISSCOUNT        (VPG_RA + RA_PREFCACHEMISSCOUNT)
#define VPC_RAEEZCULLCOUNT              (VPG_RA + RA_EEZCULLCOUNT)
#define VPC_RANONIDLESTARVECOUNT        (VPG_RA + RA_NONIDLESTARVECOUNT)
#define VPC_RASTARVELCOUNT              (VPG_RA + RA_STARVELCOUNT)
#define VPC_RASTALLCOUNT                (VPG_RA + RA_STALLCOUNT)
#define VPC_RAPROCESSCOUNT              (VPG_RA + RA_PROCESSCOUNT)

/* HW: TEX Counters. */
#define VPC_TXTOTBILINEARREQ            (VPG_TX + TX_TOTBILINEARREQ)
#define VPC_TXTOTTRILINEARREQ           (VPG_TX + TX_TOTTRILINEARREQ)
#define VPC_TXTOTDISCARDTEXREQ          (VPG_TX + TX_TOTDISCARDTEXREQ)
#define VPC_TXTOTTEXREQ                 (VPG_TX + TX_TOTTEXREQ)
#define VPC_TXMEMREADCOUNT              (VPG_TX + TX_MEMREADCOUNT)
#define VPC_TXMEMREADIN8BCOUNT          (VPG_TX + TX_MEMREADIN8BCOUNT)
#define VPC_TXCACHEMISSCOUNT            (VPG_TX + TX_CACHEMISSCOUNT)
#define VPC_TXCACHEHITTEXELCOUNT        (VPG_TX + TX_CACHEHITTEXELCOUNT)
#define VPC_TXCACHEMISSTEXELCOUNT       (VPG_TX + TX_CACHEMISSTEXELCOUNT)
#define VPC_TXNONIDLESTARVECOUNT        (VPG_TX + TX_NONIDLESTARVECOUNT)
#define VPC_TXSTARVELCOUNT              (VPG_TX + TX_STARVELCOUNT)
#define VPC_TXSTALLCOUNT                (VPG_TX + TX_STALLCOUNT)
#define VPC_TXPROCESSCOUNT              (VPG_TX + TX_PROCESSCOUNT)

/* HW: PE Counters. */
#define VPC_PEKILLEDBYCOLOR             (VPG_PE + PE_KILLEDBYCOLOR)
#define VPC_PEKILLEDBYDEPTH             (VPG_PE + PE_KILLEDBYDEPTH)
#define VPC_PEDRAWNBYCOLOR              (VPG_PE + PE_DRAWNBYCOLOR)
#define VPC_PEDRAWNBYDEPTH              (VPG_PE + PE_DRAWNBYDEPTH)

/* HW: MC Counters. */
#define VPC_MCREADREQ8BPIPE             (VPG_MC + MC_READREQ8BPIPE)
#define VPC_MCREADREQ8BIP               (VPG_MC + MC_READREQ8BIP)
#define VPC_MCWRITEREQ8BPIPE            (VPG_MC + MC_WRITEREQ8BPIPE)
#define VPC_MCAXIMINLATENCY             (VPG_MC + MC_AXIMINLATENCY)
#define VPC_MCAXIMAXLATENCY             (VPG_MC + MC_AXIMAXLATENCY)
#define VPC_MCAXITOTALLATENCY           (VPG_MC + MC_AXITOTALLATENCY)
#define VPC_MCAXISAMPLECOUNT            (VPG_MC + MC_AXISAMPLECOUNT)

/* HW: AXI Counters. */
#define VPC_AXIREADREQSTALLED           (VPG_AXI + AXI_READREQSTALLED)
#define VPC_AXIWRITEREQSTALLED          (VPG_AXI + AXI_WRITEREQSTALLED)
#define VPC_AXIWRITEDATASTALLED         (VPG_AXI + AXI_WRITEDATASTALLED)

/* HW: FE Counters. */
#define VPC_FEDRAWCOUNT                 (VPG_FE + FE_DRAWCOUNT)
#define VPC_FEOUTVERTEXCOUNT            (VPG_FE + FE_OUTVERTEXCOUNT)
#define VPC_FESTALLCOUNT                (VPG_FE + FE_STALLCOUNT)
#define VPC_FESTARVECOUNT               (VPG_FE + FE_STARVECOUNT)

/* HW: Shader Counters. */
#define VPNC_VSINSTCOUNT                 (VPNG_VS + 1)
#define VPNC_VSBRANCHINSTCOUNT           (VPNG_VS + 2)
#define VPNC_VSTEXLDINSTCOUNT            (VPNG_VS + 3)
#define VPNC_VSRENDEREDVERTCOUNT         (VPNG_VS + 4)
#define VPNC_VSNONIDLESTARVECOUNT        (VPNG_VS + 5)
#define VPNC_VSSTARVELCOUNT              (VPNG_VS + 6)
#define VPNC_VSSTALLCOUNT                (VPNG_VS + 7)
#define VPNC_VSPROCESSCOUNT              (VPNG_VS + 8)
#define VPNC_VSSHADERCYCLECOUNT          (VPNG_VS + 9)
#define VPNC_VS_COUNT                    (VPNC_VSSHADERCYCLECOUNT - VPNG_VS)

/* HW: PS Count. */
#define VPNC_PSINSTCOUNT                 (VPNG_PS + 1)
#define VPNC_PSBRANCHINSTCOUNT           (VPNG_PS + 2)
#define VPNC_PSTEXLDINSTCOUNT            (VPNG_PS + 3)
#define VPNC_PSRENDEREDPIXCOUNT          (VPNG_PS + 4)
#define VPNC_PSNONIDLESTARVECOUNT        (VPNG_PS + 5)
#define VPNC_PSSTARVELCOUNT              (VPNG_PS + 6)
#define VPNC_PSSTALLCOUNT                (VPNG_PS + 7)
#define VPNC_PSPROCESSCOUNT              (VPNG_PS + 8)
#define VPNC_PSSHADERCYCLECOUNT          (VPNG_PS + 9)
#define VPNC_PS_COUNT                    (VPNC_PSSHADERCYCLECOUNT - VPNG_PS)

/* HW: PA Counters. */
#define VPNC_PAINVERTCOUNT               (VPNG_PA + 1)
#define VPNC_PAINPRIMCOUNT               (VPNG_PA + 2)
#define VPNC_PAOUTPRIMCOUNT              (VPNG_PA + 3)
#define VPNC_PADEPTHCLIPCOUNT            (VPNG_PA + 4)
#define VPNC_PATRIVIALREJCOUNT           (VPNG_PA + 5)
#define VPNC_PACULLPRIMCOUNT             (VPNG_PA + 6)
#define VPNC_PADROPPRIMCOUNT             (VPNG_PA + 7)
#define VPNC_PAFRCLIPPRIMCOUNT           (VPNG_PA + 8)
#define VPNC_PAFRCLIPDROPPRIMCOUNT       (VPNG_PA + 9)
#define VPNC_PANONIDLESTARVECOUNT        (VPNG_PA + 10)
#define VPNC_PASTARVELCOUNT              (VPNG_PA + 11)
#define VPNC_PASTALLCOUNT                (VPNG_PA + 12)
#define VPNC_PAPROCESSCOUNT              (VPNG_PA + 13)
#define VPNC_PA_COUNT                    (VPNC_PAPROCESSCOUNT - VPNG_PA)

/* HW: Setup Counters. */
#define VPNC_SECULLTRIANGLECOUNT         (VPNG_SETUP + 1)
#define VPNC_SECULLLINECOUNT             (VPNG_SETUP + 2)
#define VPNC_SECLIPTRIANGLECOUNT         (VPNG_SETUP + 3)
#define VPNC_SECLIPLINECOUNT             (VPNG_SETUP + 4)
#define VPNC_SESTARVECOUNT               (VPNG_SETUP + 5)
#define VPNC_SESTALLCOUNT                (VPNG_SETUP + 6)
#define VPNC_SERECEIVETRIANGLECOUNT      (VPNG_SETUP + 7)
#define VPNC_SESENDTRIANGLECOUNT         (VPNG_SETUP + 8)
#define VPNC_SERECEIVELINESCOUNT         (VPNG_SETUP + 9)
#define VPNC_SESENDLINESCOUNT            (VPNG_SETUP + 10)
#define VPNC_SENONIDLESTARVECOUNT        (VPNG_SETUP + 11)
#define VPNC_SETRIVIALREJLINECOUNT       (VPNG_SETUP + 12)
#define VPNC_SEPROCESSCOUNT              (VPNG_SETUP + 13)
#define VPNC_SE_COUNT                    (VPNC_SEPROCESSCOUNT - VPNG_SETUP)

/* HW: RA Counters. */
#define VPNC_RAVALIDPIXCOUNT             (VPNG_RA + 1)
#define VPNC_RATOTALQUADCOUNT            (VPNG_RA + 2)
#define VPNC_RAVALIDQUADCOUNTEZ          (VPNG_RA + 3)
#define VPNC_RAINPUTPRIMCOUNT            (VPNG_RA + 4)
#define VPNC_RAPIPECACHEMISSCOUNT        (VPNG_RA + 5)
#define VPNC_RAPREFCACHEMISSCOUNT        (VPNG_RA + 6)
#define VPNC_RAPIPEHZCACHEMISSCOUNT      (VPNG_RA + 7)
#define VPNC_RAPREFHZCACHEMISSCOUNT      (VPNG_RA + 8)
#define VPNC_RAOUTPUTQUADCOUNT           (VPNG_RA + 9)
#define VPNC_RAOUTPUTPIXELCOUNT          (VPNG_RA + 10)
#define VPNC_RAEEZCULLCOUNT              (VPNG_RA + 11)
#define VPNC_RANONIDLESTARVECOUNT        (VPNG_RA + 12)
#define VPNC_RASTARVELCOUNT              (VPNG_RA + 13)
#define VPNC_RASTALLCOUNT                (VPNG_RA + 14)
#define VPNC_RAPROCESSCOUNT              (VPNG_RA + 15)
#define VPNC_RA_COUNT                    (VPNC_RAPROCESSCOUNT - VPNG_RA)

/* HW: TEX Counters. */
#define VPNC_TXTOTBILINEARREQ            (VPNG_TX + 1)
#define VPNC_TXTOTTRILINEARREQ           (VPNG_TX + 2)
#define VPNC_TXTOTDISCARDTEXREQ          (VPNG_TX + 3)
#define VPNC_TXTOTTEXREQ                 (VPNG_TX + 4)
#define VPNC_TXMC0MISSCOUNT              (VPNG_TX + 5)
#define VPNC_TXMC0REQCOUNT               (VPNG_TX + 6)
#define VPNC_TXMC1MISSCOUNT              (VPNG_TX + 7)
#define VPNC_TXMC1REQCOUNT               (VPNG_TX + 8)
#define VPNC_TX_COUNT                    (VPNC_TXMC1REQCOUNT - VPNG_TX)

/* HW: PE Counters. */
#define VPNC_PE0KILLEDBYCOLOR             (VPNG_PE + 1)
#define VPNC_PE0KILLEDBYDEPTH             (VPNG_PE + 2)
#define VPNC_PE0DRAWNBYCOLOR              (VPNG_PE + 3)
#define VPNC_PE0DRAWNBYDEPTH              (VPNG_PE + 4)
#define VPNC_PE1KILLEDBYCOLOR             (VPNG_PE + 5)
#define VPNC_PE1KILLEDBYDEPTH             (VPNG_PE + 6)
#define VPNC_PE1DRAWNBYCOLOR              (VPNG_PE + 7)
#define VPNC_PE1DRAWNBYDEPTH              (VPNG_PE + 8)
#define VPNC_PE_COUNT                     (VPNC_PE1DRAWNBYDEPTH - VPNG_PE)

/* HW: MCC Counters. */
#define VPNC_MCCREADREQ8BCOLORPIPE        (VPNG_MCC + 1)
#define VPNC_MCCREADREQ8BSOCOLORPIPE      (VPNG_MCC + 2)
#define VPNC_MCCWRITEREQ8BCOLORPIPE       (VPNG_MCC + 3)
#define VPNC_MCCREADREQSOCOLORPIPE        (VPNG_MCC + 4)
#define VPNC_MCCWRITEREQCOLORPIPE         (VPNG_MCC + 5)
#define VPNC_MCCREADREQ8BDEPTHPIPE        (VPNG_MCC + 6)
#define VPNC_MCCREADREQ8BSFDEPTHPIPE      (VPNG_MCC + 7)
#define VPNC_MCCWRITEREQ8BDEPTHPIPE       (VPNG_MCC + 8)
#define VPNC_MCCREADREQSFDEPTHPIPE        (VPNG_MCC + 9)
#define VPNC_MCCWRITEREQDEPTHPIPE         (VPNG_MCC + 10)
#define VPNC_MCCREADREQ8BOTHERPIPE        (VPNG_MCC + 11)
#define VPNC_MCCWRITEREQ8BOTHERPIPE       (VPNG_MCC + 12)
#define VPNC_MCCREADREQOTHERPIPE          (VPNG_MCC + 13)
#define VPNC_MCCWRITEREQOTHERPIPE         (VPNG_MCC + 14)
#define VPNC_MCCAXIMINLATENCY             (VPNG_MCC + 15)
#define VPNC_MCCAXIMAXLATENCY             (VPNG_MCC + 16)
#define VPNC_MCCAXITOTALLATENCY           (VPNG_MCC + 17)
#define VPNC_MCCAXISAMPLECOUNT            (VPNG_MCC + 18)
#define VPNC_MCCFEREADBANDWIDTH           (VPNG_MCC + 19)
#define VPNC_MCCMMUREADBANDWIDTH          (VPNG_MCC + 20)
#define VPNC_MCCBLTREADBANDWIDTH          (VPNG_MCC + 21)
#define VPNC_MCCSH0READBANDWIDTH          (VPNG_MCC + 22)
#define VPNC_MCCSH1READBANDWIDTH          (VPNG_MCC + 23)
#define VPNC_MCCPEWRITEBANDWIDTH          (VPNG_MCC + 24)
#define VPNC_MCCBLTWRITEBANDWIDTH         (VPNG_MCC + 25)
#define VPNC_MCCSH0WRITEBANDWIDTH         (VPNG_MCC + 26)
#define VPNC_MCCSH1WRITEBANDWIDTH         (VPNG_MCC + 27)
#define VPNC_MCC_COUNT                    (VPNC_MCCSH1WRITEBANDWIDTH - VPNG_MCC)

/* HW: MCZ Counters. */
#define VPNC_MCZREADREQ8BCOLORPIPE        (VPNG_MCZ + 1)
#define VPNC_MCZREADREQ8BSOCOLORPIPE      (VPNG_MCZ + 2)
#define VPNC_MCZWRITEREQ8BCOLORPIPE       (VPNG_MCZ + 3)
#define VPNC_MCZREADREQSOCOLORPIPE        (VPNG_MCZ + 4)
#define VPNC_MCZWRITEREQCOLORPIPE         (VPNG_MCZ + 5)
#define VPNC_MCZREADREQ8BDEPTHPIPE        (VPNG_MCZ + 6)
#define VPNC_MCZREADREQ8BSFDEPTHPIPE      (VPNG_MCZ + 7)
#define VPNC_MCZWRITEREQ8BDEPTHPIPE       (VPNG_MCZ + 8)
#define VPNC_MCZREADREQSFDEPTHPIPE        (VPNG_MCZ + 9)
#define VPNC_MCZWRITEREQDEPTHPIPE         (VPNG_MCZ + 10)
#define VPNC_MCZREADREQ8BOTHERPIPE        (VPNG_MCZ + 11)
#define VPNC_MCZWRITEREQ8BOTHERPIPE       (VPNG_MCZ + 12)
#define VPNC_MCZREADREQOTHERPIPE          (VPNG_MCZ + 13)
#define VPNC_MCZWRITEREQOTHERPIPE         (VPNG_MCZ + 14)
#define VPNC_MCZAXIMINLATENCY             (VPNG_MCZ + 15)
#define VPNC_MCZAXIMAXLATENCY             (VPNG_MCZ + 16)
#define VPNC_MCZAXITOTALLATENCY           (VPNG_MCZ + 17)
#define VPNC_MCZAXISAMPLECOUNT            (VPNG_MCZ + 18)
#define VPNC_MCZ_COUNT                    (VPNC_MCZAXISAMPLECOUNT - VPNG_MCZ)

/* HW: HI Counters. */
#define VPNC_HI0READ8BYTE                (VPNG_HI + 1)
#define VPNC_HI0WRITE8BYTE               (VPNG_HI + 2)
#define VPNC_HI0READREQ                  (VPNG_HI + 3)
#define VPNC_HI0WRITEREQ                 (VPNG_HI + 4)
#define VPNC_HI0AXIREADREQSTALL          (VPNG_HI + 5)
#define VPNC_HI0AXIWRITEREQSTALL         (VPNG_HI + 6)
#define VPNC_HI0AXIWRITEDATASTALL        (VPNG_HI + 7)
#define VPNC_HI1READ8BYTE                (VPNG_HI + 8)
#define VPNC_HI1WRITE8BYTE               (VPNG_HI + 9)
#define VPNC_HI1READREQ                  (VPNG_HI + 10)
#define VPNC_HI1WRITEREQ                 (VPNG_HI + 11)
#define VPNC_HI1AXIREADREQSTALL          (VPNG_HI + 12)
#define VPNC_HI1AXIWRITEREQSTALL         (VPNG_HI + 13)
#define VPNC_HI1AXIWRITEDATASTALL        (VPNG_HI + 14)
#define VPNC_HITOTALCYCLES               (VPNG_HI + 15)
#define VPNC_HIIDLECYCLES                (VPNG_HI + 16)
#define VPNC_HIREAD8BYTE                 (VPNG_HI + 17)
#define VPNC_HIWRITE8BYTE                (VPNG_HI + 18)
#define VPNC_HIOCBREAD16BYTE             (VPNG_HI + 19)
#define VPNC_HIOCBWRITE16BYTE            (VPNG_HI + 20)
#define VPNC_HI_COUNT                    (VPNC_HIOCBWRITE16BYTE - VPNG_HI)

/* HW: L2 Counters. */
#define VPNC_L2AXI0READREQCOUNT          (VPNG_L2 + 1)
#define VPNC_L2AXI1READREQCOUNT          (VPNG_L2 + 2)
#define VPNC_L2AXI0WRITEREQCOUNT         (VPNG_L2 + 3)
#define VPNC_L2AXI1WRITEREQCOUNT         (VPNG_L2 + 4)
#define VPNC_L2READTRANSREQBYAXI0        (VPNG_L2 + 5)
#define VPNC_L2READTRANSREQBYAXI1        (VPNG_L2 + 6)
#define VPNC_L2WRITETRANSREQBYAXI0       (VPNG_L2 + 7)
#define VPNC_L2WRITETRANSREQBYAXI1       (VPNG_L2 + 8)
#define VPNC_L2AXI0MINLATENCY            (VPNG_L2 + 9)
#define VPNC_L2AXI0MAXLATENCY            (VPNG_L2 + 10)
#define VPNC_L2AXI0TOTLATENCY            (VPNG_L2 + 11)
#define VPNC_L2AXI0TOTREQCOUNT           (VPNG_L2 + 12)
#define VPNC_L2AXI1MINLATENCY            (VPNG_L2 + 13)
#define VPNC_L2AXI1MAXLATENCY            (VPNG_L2 + 14)
#define VPNC_L2AXI1TOTLATENCY            (VPNG_L2 + 15)
#define VPNC_L2AXI1TOTREQCOUNT           (VPNG_L2 + 16)
#define VPNC_L2_COUNT                    (VPNC_L2AXI1TOTREQCOUNT - VPNG_L2)

/* HW: FE Counters. */
#define VPNC_FEDRAWCOUNT                 (VPNG_FE + 1)
#define VPNC_FEOUTVERTEXCOUNT            (VPNG_FE + 2)
#define VPNC_FECACHEMISSCOUNT            (VPNG_FE + 3)
#define VPNC_FECACHELKCOUNT              (VPNG_FE + 4)
#define VPNC_FESTALLCOUNT                (VPNG_FE + 5)
#define VPNC_FESTARVECOUNT               (VPNG_FE + 6)
#define VPNC_FEPROCESSCOUNT              (VPNG_FE + 7)
#define VPNC_FE_COUNT                    (VPNC_FEPROCESSCOUNT - VPNG_FE)

#define TOTAL_COUNTER_NUMBER   \
    (VPNC_FE_COUNT + VPNC_VS_COUNT + VPNC_PA_COUNT + VPNC_SE_COUNT  + VPNC_RA_COUNT  + \
     VPNC_PS_COUNT + VPNC_TX_COUNT + VPNC_PE_COUNT + VPNC_MCC_COUNT + VPNC_MCZ_COUNT + \
     VPNC_HI_COUNT + VPNC_L2_COUNT)

#define TOTAL_MODULE_NUMBER              12

/* PROGRAM: Shader program counters. */
#define VPC_PVSINSTRCOUNT           (VPG(PVS) + PVS_INSTRCOUNT)
#define VPC_PVSALUINSTRCOUNT        (VPG(PVS) + PVS_ALUINSTRCOUNT)
#define VPC_PVSTEXINSTRCOUNT        (VPG(PVS) + PVS_TEXINSTRCOUNT)
#define VPC_PVSATTRIBCOUNT          (VPG(PVS) + PVS_ATTRIBCOUNT)
#define VPC_PVSUNIFORMCOUNT         (VPG(PVS) + PVS_UNIFORMCOUNT)
#define VPC_PVSFUNCTIONCOUNT        (VPG(PVS) + PVS_FUNCTIONCOUNT)
#define VPC_PVSSOURCE               (VPG(PVS) + PVS_SOURCE)

#define VPC_PPSINSTRCOUNT           (VPG(PPS) + PPS_INSTRCOUNT)
#define VPC_PPSALUINSTRCOUNT        (VPG(PPS) + PPS_ALUINSTRCOUNT)
#define VPC_PPSTEXINSTRCOUNT        (VPG(PPS) + PPS_TEXINSTRCOUNT)
#define VPC_PPSATTRIBCOUNT          (VPG(PPS) + PPS_ATTRIBCOUNT)
#define VPC_PPSUNIFORMCOUNT         (VPG(PPS) + PPS_UNIFORMCOUNT)
#define VPC_PPSFUNCTIONCOUNT        (VPG(PPS) + PPS_FUNCTIONCOUNT)
#define VPC_PPSSOURCE               (VPG(PPS) + PPS_SOURCE)

#define VPC_PROGRAMHANDLE           (VPG(PROG) + 1)

#define VPC_ES30_DRAW_NO            (VPG(ES30_DRAW) + 1)
#define VPC_ES11_DRAW_NO            (VPG_ES11_DRAW + 1)
#define VPC_ES30_GPU_NO             (VPG(MULTI_GPU) + 1)

#define   MODULE_FRONT_END_COUNTER_NUM                    0x5
#define   MODULE_VERTEX_SHADER_COUNTER_NUM                0x9
#define   MODULE_PRIMITIVE_ASSEMBLY_COUNTER_NUM           0xC
#define   MODULE_SETUP_COUNTER_NUM                        0xD
#define   MODULE_RASTERIZER_COUNTER_NUM                   0xE
#define   MODULE_PIXEL_SHADER_COUNTER_NUM                 0x9
#define   MODULE_TEXTURE_COUNTER_NUM                      0x8
#define   MODULE_PIXEL_ENGINE_COUNTER_NUM                 0x8
#define   MODULE_MEMORY_CONTROLLER_COLOR_COUNTER_NUM      0xC
#define   MODULE_MEMORY_CONTROLLER_DEPTH_COUNTER_NUM      0xC
#define   MODULE_HOST_INTERFACE0_COUNTER_NUM              0x9
#define   MODULE_HOST_INTERFACE1_COUNTER_NUM              0x7
#define   MODULE_GPUL2_CACHE_COUNTER_NUM                  0xE
#define   MODULE_WORK_DISTRIBUTOR_COUNTER_NUM  0x0
#define   MODULE_POSITION_PA_COUNTER_NUM  0xA
#define   MODULE_FINAL_PA_COUNTER_NUM  0xB
#define   MODULE_TESS_CTRL_SHADER_COUNTER_NUM  0x9
#define   MODULE_TESS_EVAL_SHADER_COUNTER_NUM  0x9
#define   MODULE_GEOMETRY_SHADER_COUNTER_NUM  0x9
#define   MODULE_TRANSFORM_FEEDBACK_COUNTER_NUM  0x0
#define   MODULE_UNIVERSAL_STORAGE_COUNTER_NUM  0x0
#define   MODULE_DIRECTORY_COUNTER_NUM  0x0
#define   TOTAL_PROBE_NUMBER                                                        \
    (MODULE_FRONT_END_COUNTER_NUM + MODULE_VERTEX_SHADER_COUNTER_NUM +              \
     MODULE_PRIMITIVE_ASSEMBLY_COUNTER_NUM + MODULE_SETUP_COUNTER_NUM +             \
     MODULE_RASTERIZER_COUNTER_NUM + MODULE_PIXEL_SHADER_COUNTER_NUM +              \
     MODULE_TEXTURE_COUNTER_NUM + MODULE_PIXEL_ENGINE_COUNTER_NUM +                 \
     MODULE_MEMORY_CONTROLLER_COLOR_COUNTER_NUM +                                   \
     MODULE_MEMORY_CONTROLLER_DEPTH_COUNTER_NUM +                                   \
     MODULE_HOST_INTERFACE0_COUNTER_NUM + MODULE_HOST_INTERFACE1_COUNTER_NUM +      \
     MODULE_GPUL2_CACHE_COUNTER_NUM + MODULE_WORK_DISTRIBUTOR_COUNTER_NUM +         \
     MODULE_POSITION_PA_COUNTER_NUM + MODULE_FINAL_PA_COUNTER_NUM +                 \
     MODULE_TESS_CTRL_SHADER_COUNTER_NUM + MODULE_TESS_EVAL_SHADER_COUNTER_NUM +    \
     MODULE_GEOMETRY_SHADER_COUNTER_NUM + MODULE_TRANSFORM_FEEDBACK_COUNTER_NUM +   \
     MODULE_UNIVERSAL_STORAGE_COUNTER_NUM + MODULE_DIRECTORY_COUNTER_NUM)

#define   TOTAL_CL_COUNTER_NUMBER                                               \
    (\
        (VPNC_FEPROCESSCOUNT - VPNC_FECACHELKCOUNT + 1) +                       \
        VPNC_TX_COUNT + (VPNC_PS_COUNT - 1) +                                   \
        (VPNC_MCCSH1WRITEBANDWIDTH - VPNC_MCCWRITEREQDEPTHPIPE -                \
            (VPNC_MCCSH1WRITEBANDWIDTH - VPNC_MCCFEREADBANDWIDTH + 1)) +        \
        (VPNC_HI_COUNT - (VPNC_HIOCBWRITE16BYTE - VPNC_HIOCBREAD16BYTE + 1)) +  \
        VPNC_L2_COUNT                                                           \
    )
#define   TOTAL_CL_MODULE_NUMBER                (6)

#define VPNC_NN_LAYER_ID                        (VPNG_NN + 1)
#define VPNC_NN_LAYER_ID_OVFL                   (VPNG_NN + 2)
#define VPNC_NN_INSTR_INFO                      (VPNG_NN + 3)
#define VPNC_NN_TOTAL_BUSY_CYCLE                (VPNG_NN + 4)
#define VPNC_NN_TOTAL_BUSY_CYCLE_OVFL           (VPNG_NN + 5)
#define VPNC_NN_TOTAL_READ_CYCLE_DDR            (VPNG_NN + 6)
#define VPNC_NN_TOTAL_READ_CYCLE_DDR_OVFL       (VPNG_NN + 7)
#define VPNC_NN_TOTAL_READ_VALID_BW_DDR         (VPNG_NN + 8)
#define VPNC_NN_TOTAL_READ_VALID_BW_DDR_OVFL    (VPNG_NN + 9)
#define VPNC_NN_TOTAL_WRITE_CYCLE_DDR           (VPNG_NN + 10)
#define VPNC_NN_TOTAL_WRITE_CYCLE_DDR_OVFL      (VPNG_NN + 11)
#define VPNC_NN_TOTAL_WRITE_VALID_BW_DDR        (VPNG_NN + 12)
#define VPNC_NN_TOTAL_WRITE_VALID_BW_DDR_OVFL   (VPNG_NN + 13)
#define VPNC_NN_TOTAL_READ_CYCLE_SRAM           (VPNG_NN + 14)
#define VPNC_NN_TOTAL_READ_CYCLE_SRAM_OVFL      (VPNG_NN + 15)
#define VPNC_NN_TOTAL_WRITE_CYCLE_SRAM          (VPNG_NN + 16)
#define VPNC_NN_TOTAL_WRITE_CYCLE_SRAM_OVFL     (VPNG_NN + 17)
#define VPNC_NN_TOTAL_MAC_CYCLE                 (VPNG_NN + 18)
#define VPNC_NN_TOTAL_MAC_CYCLE_OVFL            (VPNG_NN + 19)
#define VPNC_NN_TOTAL_MAC_COUNT                 (VPNG_NN + 20)
#define VPNC_NN_TOTAL_MAC_COUNT_OVFL            (VPNG_NN + 21)
#define VPNC_NN_ZERO_COEF_SKIP_COUNT            (VPNG_NN + 22)
#define VPNC_NN_ZERO_COEF_SKIP_COUNT_OVFL       (VPNG_NN + 23)
#define VPNC_NN_NON_ZERO_COEF_COUNT             (VPNG_NN + 24)
#define VPNC_NN_NON_ZERO_COEF_COUNT_OVFL        (VPNG_NN + 25)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE_OVFL      (VPNG_NN + 26)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE0          (VPNG_NN + 27)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE1          (VPNG_NN + 28)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE2          (VPNG_NN + 29)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE3          (VPNG_NN + 30)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE4          (VPNG_NN + 31)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE5          (VPNG_NN + 32)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE6          (VPNG_NN + 33)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE7          (VPNG_NN + 34)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE8          (VPNG_NN + 35)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE9          (VPNG_NN + 36)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE10         (VPNG_NN + 37)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE11         (VPNG_NN + 38)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE12         (VPNG_NN + 39)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE13         (VPNG_NN + 40)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE14         (VPNG_NN + 41)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE15         (VPNG_NN + 42)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE16         (VPNG_NN + 43)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE17         (VPNG_NN + 44)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE18         (VPNG_NN + 45)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE19         (VPNG_NN + 46)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE20         (VPNG_NN + 47)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE21         (VPNG_NN + 48)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE22         (VPNG_NN + 49)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE23         (VPNG_NN + 50)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE24         (VPNG_NN + 51)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE25         (VPNG_NN + 52)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE26         (VPNG_NN + 53)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE27         (VPNG_NN + 54)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE28         (VPNG_NN + 55)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE29         (VPNG_NN + 56)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE30         (VPNG_NN + 57)
#define VPNC_NN_TOTAL_IDLE_CYCLE_CORE31         (VPNG_NN + 58)
#define VPNC_NN_COUNT                           (VPNC_NN_TOTAL_IDLE_CYCLE_CORE31 - VPNG_NN)

/* HW: TP Probe Counters. */
#define VPNC_TP_LAYER_ID                      (VPNG_TP + 1)
#define VPNC_TP_LAYER_ID_OVFL                 (VPNG_TP + 2)
#define VPNC_TP_TOTAL_BUSY_CYCLE              (VPNG_TP + 3)
#define VPNC_TP_TOTAL_BUSY_CYCLE_OVFL         (VPNG_TP + 4)
#define VPNC_TP_TOTAL_READ_BW_CACHE           (VPNG_TP + 5)
#define VPNC_TP_TOTAL_READ_BW_CACHE_OVFL      (VPNG_TP + 6)
#define VPNC_TP_TOTAL_WRITE_BW_CACHE          (VPNG_TP + 7)
#define VPNC_TP_TOTAL_WRITE_BW_CACHE_OVFL     (VPNG_TP + 8)
#define VPNC_TP_TOTAL_READ_BW_SRAM            (VPNG_TP + 9)
#define VPNC_TP_TOTAL_READ_BW_SRAM_OVFL       (VPNG_TP + 10)
#define VPNC_TP_TOTAL_WRITE_BW_SRAM           (VPNG_TP + 11)
#define VPNC_TP_TOTAL_WRITE_BW_SRAM_OVFL      (VPNG_TP + 12)
#define VPNC_TP_TOTAL_READ_BW_OCB             (VPNG_TP + 13)
#define VPNC_TP_TOTAL_READ_BW_OCB_OVFL        (VPNG_TP + 14)
#define VPNC_TP_TOTAL_WRITE_BW_OCB            (VPNG_TP + 15)
#define VPNC_TP_TOTAL_WRITE_BW_OCB_OVFL       (VPNG_TP + 16)
#define VPNC_TP_FC_PIX_CNT                    (VPNG_TP + 17)
#define VPNC_TP_FC_ZERO_SKIP_CNT              (VPNG_TP + 18)
#define VPNC_TP_FC_PIX_CNT_OVFL               (VPNG_TP + 19)
#define VPNC_TP_FC_ZERO_SKIP_CNT_OVFL         (VPNG_TP + 20)
#define VPNC_TP_FC_COEF_CNT                   (VPNG_TP + 21)
#define VPNC_TP_FC_COEF_ZERO_CNT              (VPNG_TP + 22)
#define VPNC_TP_FC_COEF_CNT_OVFL              (VPNG_TP + 23)
#define VPNC_TP_FC_COEF_ZERO_CNT_OVFL         (VPNG_TP + 24)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE0        (VPNG_TP + 25)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE0_OVFL   (VPNG_TP + 26)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE1        (VPNG_TP + 27)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE1_OVFL   (VPNG_TP + 28)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE2        (VPNG_TP + 29)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE2_OVFL   (VPNG_TP + 30)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE3        (VPNG_TP + 31)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE3_OVFL   (VPNG_TP + 32)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE4        (VPNG_TP + 33)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE4_OVFL   (VPNG_TP + 34)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE5        (VPNG_TP + 35)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE5_OVFL   (VPNG_TP + 36)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE6        (VPNG_TP + 37)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE6_OVFL   (VPNG_TP + 38)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE7        (VPNG_TP + 39)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE7_OVFL   (VPNG_TP + 40)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE8        (VPNG_TP + 41)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE8_OVFL   (VPNG_TP + 42)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE9        (VPNG_TP + 43)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE9_OVFL   (VPNG_TP + 44)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE10       (VPNG_TP + 45)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE10_OVFL  (VPNG_TP + 46)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE11       (VPNG_TP + 47)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE11_OVFL  (VPNG_TP + 48)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE12       (VPNG_TP + 49)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE12_OVFL  (VPNG_TP + 50)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE13       (VPNG_TP + 51)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE13_OVFL  (VPNG_TP + 52)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE14       (VPNG_TP + 53)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE14_OVFL  (VPNG_TP + 54)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE15       (VPNG_TP + 55)
#define VPNC_TP_TOTAL_IDLE_CYCLE_CORE15_OVFL  (VPNG_TP + 56)
#define VPNC_TP_COUNT                         (VPNC_TP_TOTAL_IDLE_CYCLE_CORE15_OVFL - VPNG_TP)

#define   MODULE_NN_BASE_COUNTER_NUM          0x6
/*#define   MODULE_NN_RESERVED_COUNTER_NUM           0x9*/
#define   MODULE_NN_IDLE_COUNTER_NUM          0x9
#define   MODULE_NN_COUNTER_NUM               (MODULE_NN_BASE_COUNTER_NUM + MODULE_NN_RESERVED_COUNTER_NUM + MODULE_NN_IDLE_COUNTER_NUM)

#define  TOTAL_VIP_COUNTER_NUMBER       (VPNC_TP_COUNT + VPNC_NN_COUNT)
#define   TOTAL_VIP_MODULE_NUMBER       2
#define   MODULE_TP_COUNTER_NUM         0xE
#define   TOTAL_VIP_PROBE_NUMBER        (MODULE_NN_COUNTER_NUM + MODULE_TP_COUNTER_NUM)

#ifdef ANDROID
# define DEFAULT_PROFILE_FILE_NAME   "/sdcard/vprofiler.vpd"
#else
# define DEFAULT_PROFILE_FILE_NAME   "vprofiler.vpd"
#endif

#define VPHEADER_VERSION                "VP20"

#define VPFILETYPE_GL                   "10"

#define VPFILETYPE_CL                   "00"

#if gcdENDIAN_BIG
# define BIG_ENDIAN_TRANS_INT(x)                                          \
    ((gctUINT32)((((gctUINT32)(x) & (gctUINT32)0x000000FFUL) << 24) |     \
                 (((gctUINT32)(x) & (gctUINT32)0x0000FF00UL) << 8)  |     \
                 (((gctUINT32)(x) & (gctUINT32)0x00FF0000UL) >> 8)  |     \
                 (((gctUINT32)(x) & (gctUINT32)0xFF000000UL) >> 24)))
#else
# define BIG_ENDIAN_TRANS_INT(x) x
#endif

/* Write a data value. */
#define gcmWRITE_VALUE(IntData)                                               \
    do {                                                                      \
        gceSTATUS status;                                                     \
        gctINT32  value = IntData;                                            \
        value           = BIG_ENDIAN_TRANS_INT(value);                        \
        gcmERR_BREAK(gcoPROFILER_Write(Profiler, gcmSIZEOF(value), &value));  \
    } while (gcvFALSE)

#define gcmWRITE_CONST(Const)                                                 \
    do {                                                                      \
        gceSTATUS status;                                                     \
        gctINT32  data = Const;                                               \
        data           = BIG_ENDIAN_TRANS_INT(data);                          \
        gcmERR_BREAK(gcoPROFILER_Write(Profiler, gcmSIZEOF(data), &data));    \
    } while (gcvFALSE)

#define gcmWRITE_COUNTER(Counter, Value)                                      \
    do {                                                                      \
        gcmWRITE_CONST(Counter);                                              \
        gcmWRITE_VALUE(Value);                                                \
    } while (gcvFALSE)

/* Write a data value. */
#define gcmRECORD_VALUE(IntData)                                              \
    do {                                                                      \
        gctINT32 value              = IntData;                                \
        value                       = BIG_ENDIAN_TRANS_INT(value);            \
        counterData[counterIndex++] = value;                                  \
    } while (gcvFALSE)

#define gcmRECORD_CONST(Const)                                                \
    do {                                                                      \
        gctINT32 data               = Const;                                  \
        data                        = BIG_ENDIAN_TRANS_INT(data);             \
        counterData[counterIndex++] = data;                                   \
    } while (gcvFALSE)

#define gcmRECORD_COUNTER(Counter, Value)                                     \
    do {                                                                      \
        gcmRECORD_CONST(Counter);                                             \
        gcmRECORD_VALUE(Value);                                               \
    } while (gcvFALSE)

/* Write a string value (char*). */
#define gcmWRITE_STRING(String)                                                          \
    do {                                                                                 \
        gceSTATUS status;                                                                \
        gctINT32  length;                                                                \
        length = (gctINT32)gcoOS_StrLen((gctSTRING)String, gcvNULL);                     \
        length = BIG_ENDIAN_TRANS_INT(length);                                           \
        gcmERR_BREAK(gcoPROFILER_Write(Profiler, gcmSIZEOF(length), &length));           \
        gcmERR_BREAK(gcoPROFILER_Write(Profiler, length, String));                       \
    } while (gcvFALSE)

#define gcmWRITE_BUFFER(Size, Buffer)                                                    \
    do {                                                                                 \
        gceSTATUS status;                                                                \
        gcmERR_BREAK(gcoPROFILER_Write(Profiler, Size, Buffer));                         \
    } while (gcvFALSE)

#define gcmGET_COUNTER(counter, counterId)                                               \
    do {                                                                                 \
        if (*(memory + (counterId + offset) * (1 << clusterIDWidth)) == 0xdeaddead) {    \
            counter = 0xdeaddead;                                                        \
        } else {                                                                         \
            gctUINT32     i;                                                             \
            gctUINT32_PTR Memory             = memory;                                   \
            gctUINT32     total_probe_number = 0;                                        \
            counter                          = 0;                                        \
            gcmONERROR(gcoPROFILER_GetProbeNumber(Hardware, &total_probe_number));       \
            Memory = memory + total_probe_number * CoreId * (1 << clusterIDWidth);       \
            for (i = 0; i < (gctUINT32)(1 << clusterIDWidth); i++) {                     \
                counter += *(Memory + (counterId + offset) * (1 << clusterIDWidth) + i); \
            }                                                                            \
        }                                                                                \
    } while (gcvFALSE)

#define gcmGET_MAXCOUNTER(counter, counterId)                                                   \
    do {                                                                                        \
        if (*(memory + (counterId + offset) * (1 << clusterIDWidth)) == 0xdeaddead) {           \
            counter = 0xdeaddead;                                                               \
        } else {                                                                                \
            gctUINT32 i;                                                                        \
            gctUINT32_PTR Memory = memory;                                                      \
            gctUINT32 total_probe_number = 0;                                                   \
            gctUINT32 max_counter = 0;                                                          \
                                                                                                \
            counter = 0;                                                                        \
            gcmONERROR(gcoPROFILER_GetProbeNumber(Hardware, &total_probe_number));              \
            Memory = memory + total_probe_number * CoreId * (1 << clusterIDWidth);              \
            for (i = 0; i < (gctUINT32)(1 << clusterIDWidth); i++) {                            \
                if (max_counter < *(Memory + (counterId + offset) * (1 << clusterIDWidth) + i)) \
                    max_counter = *(Memory + (counterId + offset) * (1 << clusterIDWidth) + i); \
            }                                                                                   \
            counter = max_counter;                                                              \
        }                                                                                       \
    } while (gcvFALSE)

#define gcmGET_MINCOUNTER(counter, counterId)                                                   \
    do {                                                                                        \
        if (*(memory + (counterId + offset) * (1 << clusterIDWidth)) == 0xdeaddead) {           \
            counter = 0xdeaddead;                                                               \
        } else {                                                                                \
            gctUINT32 i;                                                                        \
            gctUINT32_PTR Memory = memory;                                                      \
            gctUINT32 total_probe_number = 0;                                                   \
            gctUINT32 min_counter = 0;                                                          \
            counter = 0;                                                                        \
            gcmONERROR(gcoPROFILER_GetProbeNumber(Hardware, &total_probe_number));              \
            Memory = memory + total_probe_number * CoreId * (1 << clusterIDWidth);              \
            min_counter = *(Memory + (counterId + offset) * (1 << clusterIDWidth));             \
            for (i = 0; i < (gctUINT32)(1 << clusterIDWidth); i++) {                            \
            if (Profiler->isDebugCounter) \
            { \
                gcmPRINT("%s %d hi_total_idle_cycle_count CoreId=%d clusterId=%d offset=%u cpuaddress=%p value=%u", __FUNCTION__, __LINE__, CoreId, i, offset, (Memory + (counterId + offset) * (1 << clusterIDWidth) + i), *(Memory + (counterId + offset) * (1 << clusterIDWidth) + i)); \
            } \
                if (min_counter > *(Memory + (counterId + offset) * (1 << clusterIDWidth) + i)) \
                    min_counter = *(Memory + (counterId + offset) * (1 << clusterIDWidth) + i); \
            }                                                                                   \
            counter = min_counter;                                                              \
        }                                                                                       \
    } while (gcvFALSE)

#define gcmGET_VIPCOUNTER(counter, counterId)                                            \
    do {                                                                                 \
        if (*(memory + (counterId + offset) * (1 << clusterIDWidth)) == 0xdeaddead) {    \
            counter = 0xdeaddead;                                                        \
        } else {                                                                         \
            gctUINT32     i;                                                             \
            gctUINT32_PTR Memory = memory;                                               \
            counter = 0;                                                                 \
            Memory  = memory + TOTAL_VIP_PROBE_NUMBER * CoreId * (1 << clusterIDWidth);  \
            for (i = 0; i < (gctUINT32)(1 << clusterIDWidth); i++) {                     \
                counter += *(Memory + (counterId + offset) * (1 << clusterIDWidth) + i); \
            }                                                                            \
        }                                                                                \
    } while (gcvFALSE)

#define gcmGET_LATENCY_COUNTER(minLatency, maxLatency, counterId)                                      \
    do {                                                                                               \
        if (*(memory + (counterId + offset) * (1 << clusterIDWidth)) == 0xdeaddead) {                  \
            minLatency = 0xdeaddead;                                                                   \
            maxLatency = 0xdeaddead;                                                                   \
        } else {                                                                                       \
            gctUINT32     i;                                                                           \
            gctUINT32_PTR Memory             = memory;                                                 \
            gctUINT32     total_probe_number = 0;                                                      \
            gcmONERROR(gcoPROFILER_GetProbeNumber(Hardware, &total_probe_number));                     \
            Memory = memory + total_probe_number * CoreId * (1 << clusterIDWidth);                     \
            for (i = 0; i < (gctUINT32)(1 << clusterIDWidth); i++) {                                   \
                maxLatency +=                                                                          \
                    ((*(Memory + (counterId + offset) * (1 << clusterIDWidth) + i) & 0xfff000) >> 12); \
                minLatency +=                                                                          \
                    (*(Memory + (counterId + offset) * (1 << clusterIDWidth) + i) & 0x000fff);         \
                if (minLatency == 4095)                                                                \
                    minLatency = 0;                                                                    \
            }                                                                                          \
        }                                                                                              \
    } while (gcvFALSE)

#define NumOfPerFrameBuf        16
#define NumOfPerDrawBuf         128

struct _gcsAppInfoCounter {
    gctUINT32                   count[7];
};

typedef struct _gcsAppInfoCounter gcsAppInfoCounter;

typedef struct gcsCounterBuffer   *gcsCounterBuffer_PTR;

struct gcsCounterBuffer {
    gctPOINTER                      counters;
    gcsPROFILER_VIP_PROBE_COUNTERS *vipCounters;
    gctHANDLE                       couterBufobj;
    gctADDRESS                      probeAddress;
    gctPOINTER                      logicalAddress;
    gceCOUNTER_OPTYPE               opType;
    gctUINT32                       opID;
    gcsAppInfoCounter               opCount;
    gctUINT32                       currentShaderId[6];
    gctUINT32                       startPos;
    gctUINT32                       endPos;
    gctUINT32                       dataSize;
    gctBOOL                         available;
    gctBOOL                         needDump;
    gcsCounterBuffer_PTR            next;
    gcsCounterBuffer_PTR            prev;
};

typedef struct _gcoPROBE            gcoPROBE;
struct _gcoPROBE {
    gctUINT32                   address;
    gctUINT32                   offset;
};

typedef struct _gcoMODULE           gcoMODULE;
struct _gcoMODULE {
    gctUINT32                   name;
    gctUINT32                   address;
    gctUINT32                   numProbe;
    gcoPROBE                    probe[256];
};

typedef struct _gcoPROFILER         *gcoPROFILER;

struct _gcoPROFILER {
    gctBOOL                     enable;
    gctBOOL                     enablePrint;
    gctBOOL                     disableProbe;

    gctBOOL                     vipProbe;

    gctFILE                     file;
    gctCHAR                    *fileName;
    gceProfilerMode             profilerMode;
    gceProbeMode                probeMode;

    gcsCounterBuffer_PTR        counterBuf;
    gcsAppInfoCounter           currentOpCount;
    gctUINT32                   bufferCount;

    gctBOOL                     perDrawMode;
    gctBOOL                     needDump;
    gctBOOL                     counterEnable;

    gceProfilerClient           profilerClient;

    gctBOOL                     needBltDump;
    gctBOOL                     isDummyDraw;
    gctBOOL                     isDebugCounter;
    gctUINT32                   rdByte;
    gctUINT32                   wrByte;
    gctUINT32                   busyCycle;

    /*query some features from hw*/
    gctUINT32                   coreCount;
    gctUINT32                   shaderCoreCount;
    gctBOOL                     bHalti4;
    gctBOOL                     psRenderPixelFix;
    gctBOOL                     axiBus128bits;
    gctBOOL                     bZDP3;
};

typedef struct _gcsPROBESTATES {
    gceProbeStatus              status;
    gctADDRESS                  probeAddress;
} gcsPROBESTATES;

typedef struct _gckPROFILER {
    /* Enable profiling */
    gctBOOL                     profileEnable;
    /* Profile mode */
    gceProfilerMode             profileMode;
    /* Probe mode */
    gceProbeMode                probeMode;
    /* Clear profile register or not*/
    gctBOOL                     profileCleanRegister;
    /* Profile counter */
    gcsPROFILER_COUNTERS_PART1  latestProfiler_part1;
    gcsPROFILER_COUNTERS_PART1  histroyProfiler_part1;
    gcsPROFILER_COUNTERS_PART1  preProfiler_part1;
    gcsPROFILER_COUNTERS_PART2  latestProfiler_part2;
    gcsPROFILER_COUNTERS_PART2  histroyProfiler_part2;
    gcsPROFILER_COUNTERS_PART2  preProfiler_part2;
} gckPROFILER;

/* Construct a Profiler object per context. */
gceSTATUS
gcoPROFILER_Construct(OUT gcoPROFILER *Profiler);

gceSTATUS
gcoPROFILER_Destroy(IN gcoPROFILER Profiler);

gceSTATUS
gcoPROFILER_Initialize(IN gcoPROFILER Profiler);

gceSTATUS
gcoPROFILER_Enable(IN gcoPROFILER Profiler);

gceSTATUS
gcoPROFILER_Disable(void);

gceSTATUS
gcoPROFILER_EnableCounters(IN gcoPROFILER Profiler,
                           IN gceCOUNTER_OPTYPE operationType);

gceSTATUS
gcoPROFILER_Start(IN gcoPROFILER Profiler);

gceSTATUS
gcoPROFILER_End(IN gcoPROFILER Profiler,
                IN gceCOUNTER_OPTYPE operationType,
                IN gctUINT32 OpID);

gceSTATUS
gcoPROFILER_Write(IN gcoPROFILER Profiler,
                  IN gctSIZE_T ByteCount,
                  IN gctCONST_POINTER Data);

gceSTATUS
gcoPROFILER_Flush(IN gcoPROFILER Profiler);

gceSTATUS
gcoPROFILER_GetProbeNumber(IN gcoHARDWARE Hardware,
                           OUT gctUINT32 *TotalProbeNumber);

gctUINT32
gcoPROFILER_getMuduleNum(IN gcoPROFILER Profiler);

gctUINT32
gcoPROFILER_getMuduleProbeNum(IN gcoPROFILER Profiler, IN gctUINT32 index);

gctUINT32
gcoPROFILER_getModuleAddress(IN gcoPROFILER Profiler, IN gctUINT32 ModuleIndex);

gctUINT32
gcoPROFILER_getProbeAddress(IN gcoPROFILER Profiler,
                            IN gctUINT32 ModuleIndex,
                            IN gctUINT32 ProbeIndex);

gctUINT32
gcoPROFILER_getHIIndex(IN gcoPROFILER Profiler);

gctUINT32
gcoPROFILER_getCounterBufferSize(IN gcoPROFILER Profiler);

gceSTATUS
gcoPROFILER_WriteChipInfo(IN gcoPROFILER Profiler);

gceSTATUS
gcoPROFILER_WriteClusterInfo(IN gcoPROFILER Profiler);

gceSTATUS
gcoPROFILER_Reset(IN gcoPROFILER Profiler);

gceSTATUS
gcoPROFILER_WriteCounters(IN gcoPROFILER Profiler);

#ifdef __cplusplus
}
#endif

#endif /* __gc_hal_profiler_h_ */
